package com.uam.core.business.help;

import com.alibaba.fastjson.JSONArray;
import com.uam.core.business.mode.UamDataModelV2;
import com.uam.core.entity.model.PolygonV1;
import com.uam.core.entity.uitls.DateUtils;
import com.uam.core.vo.CoordinateSegment;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.LineSegment;
import com.mapbox.geojson.Point;
import com.mapbox.turf.TurfConstants;
import com.mapbox.turf.TurfMeasurement;
import java.text.ParseException;
import java.util.*;

/**
 * Created by heguanglong   on 2017/7/11.
 */
public class IntersectinTime {
    /**
     * 获取两个图形相交信息的方法。
     * 该方法通过检查给定时间段内的线段是否与多边形相交，来确定是否存在相交情况。
     * 如果存在相交，则返回相交信息，否则返回null。
     *
     * @param segmentMap 包含线段和对应时间的映射，表示不同时间点的线段状态。
     * @param polygonV1 待检查相交的多边形对象。
     * @return 如果存在相交，则返回相交信息对象；否则返回null。
     * @throws ParseException 如果解析多边形点时发生错误。
     */
    public static IntersectinInfo getIntersectinInfo(Map<String, LineSegment> segmentMap, PolygonV1 polygonV1) throws ParseException {
        Map<String, LineSegment> oneSegmentMap= pointsToSegment(polygonV1.getPoints());
        //判断在相同的时间点内是否相交，如果相交，则就是碰撞
        List<IntersectinInfo> dataList=new ArrayList<>(16);
        for(Map.Entry<String, LineSegment> entry:segmentMap.entrySet()){
            String time=entry.getKey();
            LineSegment segment=entry.getValue();
            LineSegment lineSegment=oneSegmentMap.get(time);
            if(lineSegment!=null){
               CoordinateSegment coordinateSegmentTemp=   (CoordinateSegment)segment.p0;
               if(coordinateSegmentTemp.getIndex()<4){
                   continue;
               }
                Coordinate coordinate= segment.intersection(lineSegment);
                if(coordinate ==null){
                    dataList.add( new IntersectinInfo((CoordinateSegment)segment.p0,(CoordinateSegment)segment.p1,(CoordinateSegment)lineSegment.p0,(CoordinateSegment)lineSegment.p1,time,coordinate));
                }
            }
        }
        //取dataList的中间点
        if(dataList.size()>0){
            Collections.sort(dataList, new Comparator<IntersectinInfo>() {
                @Override
                public int compare(IntersectinInfo o1, IntersectinInfo o2) {
                    return o1.getTimeKey().compareTo(o2.getTimeKey());
                }
            });
            return dataList.get(dataList.size()/2);
        }
        return null;
    }

    /**
     * 将点集转换为线段集合。
     * 该方法通过解析JSON数组中的点信息，构建线段。每个点包含x、y坐标和时间信息。
     * 方法首先遍历点集，连接相邻的点以形成线段。然后，根据相邻点的时间差，插入中间点以细化线段。
     * 最后，将所有线段转换为一个映射，其中键是线段的唯一标识，值是线段对象。
     *
     * @param points JSON数组，包含点的集合。每个点是一个JSON对象，其中第4个元素是时间。
     * @return 返回一个映射，其中包含由点集生成的线段。
     * @throws ParseException 如果解析JSON数组时发生错误，则抛出此异常。
     */
    public  static  Map<String, LineSegment> pointsToSegment(JSONArray points) throws ParseException {
        int row=points.size();
        List<UamDataModelV2> list=new ArrayList<>(1024);
        for(int i=0;i<row-2;i++){
            JSONArray jsonArray0=points.getJSONArray(i);
            JSONArray jsonArray1=points.getJSONArray(i+1);
            getLineSegmentMapOne(points,i,jsonArray0.getLong(4),jsonArray1.getLong(4),list);
        }
        Map<String, LineSegment> data=  getLineSegmentMap(list);
        outPoint(points,list,data);
        return data;
    }

    private static void outPoint(JSONArray points,List<UamDataModelV2> list,Map<String, LineSegment> data){
        System.out.println("补点前："+points);

        JSONArray jsonArray=new JSONArray(1024);
        for(int i=0;i<list.size();i++){
            UamDataModelV2 jsonArray0=list.get(i);
            JSONArray jsonArray1=new JSONArray(2);
            jsonArray1.add(jsonArray0.getLonNow());
            jsonArray1.add(jsonArray0.getLatNow());
            jsonArray1.add(jsonArray0.getTime());
            jsonArray.add(jsonArray1);
//            System.out.println(DateUtils.format(new Date(jsonArray0.getTime())));
        }
        System.out.println("补点后："+jsonArray);

//        data.keySet().forEach(s-> System.out.println(s+"==="+data.get(s)));
    }

    private static void getLineSegmentMapOne(JSONArray points,int i,long time,long time2, List<UamDataModelV2> list) throws ParseException {
        JSONArray jsonArray0=points.getJSONArray(i);
        JSONArray jsonArray1=points.getJSONArray(i+1);
        int min= (int) (time2-time)/1000;
        //距离
        String startPoint=jsonArray0.getDouble(0)+","+jsonArray0.getDouble(1);
        String startPoint2=jsonArray1.getDouble(0)+","+jsonArray1.getDouble(1);
        double dis= CoordUtil.pointDistance(startPoint,startPoint2);

        //每秒的距离
        double distanceMin=dis/min;
        //夹角
        Point currPoint = Point.fromLngLat(jsonArray0.getDouble(0), jsonArray0.getDouble(1));
        Point nextPoint = Point.fromLngLat(jsonArray1.getDouble(0), jsonArray1.getDouble(1));
        double angle = TurfMeasurement.bearing(currPoint,nextPoint);

        UamDataModelV2 dataModelV2= new  UamDataModelV2(jsonArray0.getDouble(0),jsonArray0.getDouble(1),time,i,i+1,jsonArray1.getDouble(0),jsonArray1.getDouble(1));
        list.add(dataModelV2);
//        Point timePoint= Point.fromLngLat(jsonArray0.getDouble(0), jsonArray0.getDouble(1));
        for(int h=0;h<min-1;h++){
            long tempTime=list.get(list.size()-1).time+1000;
//            Point  timePointNow=TurfMeasurement.destination(timePoint, distanceMin, angle, TurfConstants.UNIT_METERS);
            list.add(new  UamDataModelV2(currPoint.longitude(),currPoint.latitude(),tempTime,i,i+1,nextPoint.longitude(),nextPoint.latitude()));
//            timePoint=Point.fromLngLat(timePointNow.longitude(),timePointNow.latitude());
        }
    }

    /**
     * 线拆分成线段
     *
     * @param points
     * @return
     */
    public static Map<String, LineSegment> getLineSegmentList(JSONArray points) throws ParseException {
        int row=points.size();
        List<UamDataModelV2> list=new ArrayList<>(1024);
        for(int i=2;i<row-2;i++){
            JSONArray jsonArray0=points.getJSONArray(i);
            JSONArray jsonArray1=points.getJSONArray(i+1);
            getLineSegmentMapOne(points,i,jsonArray0.getDate(4).getTime(),jsonArray1.getDate(4).getTime(),list);
        }
        Map<String, LineSegment> data=  getLineSegmentMap(list);
        outPoint(points,list,data);
        return data;
    }

    private static Map<String, LineSegment> getLineSegmentMap(List<UamDataModelV2> points) throws ParseException {
        Map<String, LineSegment> map = new LinkedHashMap<>();
        int row = points.size();
        for (int i = 0; i < row ; i++) {
            UamDataModelV2 one = points.get(i);
            CoordinateSegment coordinateOne = new CoordinateSegment(one.getLonNow(), one.getLatNow(), one.getIndexNow(), new Date(one.getTime()));
            CoordinateSegment coordinateTwo = new CoordinateSegment(one.getLonNext(), one.getLatNext(), one.getIndexNext(), new Date(one.getTime()));
            LineSegment lineStringSegment = new LineSegment(coordinateOne, coordinateTwo);
            map.put(DateUtils.format(coordinateOne.getTime()), lineStringSegment);
        }
        return map;
    }
}
